package com.uinnova.product.eam.workable.execution;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.uinnova.product.eam.feign.workable.entity.FLOWACTION;
import com.uinnova.product.eam.workable.util.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Map;

/**
 * flowable会签判断执行器
 *
 * @author lichong
 * @since 2022/2/25 16:50
 */
@Slf4j
@Component(value = "multiInstanceCompleteExecution")
public class MultiInstanceCompleteExecution implements Serializable {

    @Resource
    private RestTemplate restTemplate;

    @Value("${batch.modify.workbench.task}")
    private String batchModifyStatusUrl;

    @Resource
    private HttpUtil httpUtil;

    /**
     * 通过规则为：全员审批完，有一个人拒绝就拒绝
     *
     * @param execution
     * @return
     */
    public Boolean rejectByOneUserCondition(DelegateExecution execution) {

        Map<String, Object> variables = execution.getVariables();
        Object agreePersonNumObject = variables.get("agreePersonNum");
        int agreePersonNum = 0;
        Object rejectPersonNumObject = variables.get("rejectPersonNum");
        int rejectPersonNum = 0;
        if (rejectPersonNumObject != null) {
            rejectPersonNum = (int) rejectPersonNumObject;
        }
        if (agreePersonNumObject != null) {
            agreePersonNum = (int) agreePersonNumObject;
        }
        Object pass = variables.get("pass");
        if (pass != null) {
            if ("pass".equals(pass.toString())) {
                agreePersonNum = agreePersonNum + 1;
                execution.setVariable("agreePersonNum", agreePersonNum);
            } else {
                rejectPersonNum = rejectPersonNum + 1;
                execution.setVariable("rejectPersonNum", rejectPersonNum);
            }

        } else {
            return Boolean.FALSE;
        }

        //已完成的实例数
        int completedInstance = (int) execution.getVariable("nrOfCompletedInstances");
        //获取所有的实例数
        int allInstance = (int) execution.getVariable("nrOfInstances");
        if (completedInstance >= allInstance) {
            if (rejectPersonNum > 0) {
                execution.setVariable("goOut", "noPass");
            } else {
                execution.setVariable("goOut", "pass");
            }
            //清理变量
            execution.setVariable("agreePersonNum", 0);
            execution.setVariable("rejectPersonNum", 0);
            return true;
        } else {
            return false;
        }
    }


    /**
     * 通过规则为：有一个人拒绝就拒绝
     *
     * @param execution
     * @return
     */
    public Boolean rejectByOneUserConditionImmediately(DelegateExecution execution) {

        Map<String, Object> variables = execution.getVariables();
        Object pass = variables.get("pass");
        if (!"pass".equals(pass.toString())) {
            execution.setVariable("goOut", "noPass");
            return Boolean.TRUE;
        }

        //已完成的实例数
        int completedInstance = (int) execution.getVariable("nrOfCompletedInstances");
        //获取所有的实例数
        int allInstance = (int) execution.getVariable("nrOfInstances");
        if (completedInstance >= allInstance) {
            execution.setVariable("goOut", "pass");
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过规则为：全员审批完，有一个人同意就同意
     *
     * @param execution
     * @return
     */
    public Boolean acceptByOneUserCondition(DelegateExecution execution) {
        //已完成的实例数
        int completedInstance = (int) execution.getVariable("nrOfCompletedInstances");
        //获取所有的实例数
        int allInstance = (int) execution.getVariable("nrOfInstances");
        if (completedInstance >= allInstance) {
            int agreePersonNum = (int) execution.getVariable("agreePersonNum");
            if (agreePersonNum > 0) {
                execution.setVariable("action", FLOWACTION.ACCETP.toString());
            } else {
                execution.setVariable("action", FLOWACTION.REJECT.toString());
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过规则为：多人审批，有一个人审批通过直接通过
     *
     * @param execution
     * @return
     */
    public Boolean acceptByOneUserWhenAccept(DelegateExecution execution) {
        //已完成的实例数
        int completedInstance = (int) execution.getVariable("nrOfCompletedInstances");
        //获取所有的实例数
        int allInstance = (int) execution.getVariable("nrOfInstances");
        int agreePersonNum = (int) execution.getVariable("agreePersonNum");
        if (agreePersonNum > 0) {
            execution.setVariable("action", FLOWACTION.ACCETP.toString());
            return Boolean.TRUE;
        }
        if (completedInstance >= allInstance) {
            execution.setVariable("action", FLOWACTION.REJECT.toString());
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 通过规则为：有一个人处理就结束会签
     *
     * @param execution
     * @return
     */
    public Boolean executeByOneUserConditionImmediately(DelegateExecution execution) {
        Map<String, Object> variables = execution.getVariables();
        Object curTaskId = "";
        if (variables.get("curTaskId") != null) {
            curTaskId = variables.get("curTaskId").toString();
        }
        Object pass = variables.get("pass");
        if ("pass".equals(pass.toString())) {
            execution.setVariable("goOut", "pass");
        }else if("cancel".equals(pass.toString())){
            execution.setVariable("pass", "cancel");
            execution.setVariable("goOut", "cancel");
        }else if("noPass".equals(pass.toString())){
            execution.setVariable("goOut", "noPass");
        }else if("recall".equals(pass.toString())){
            execution.setVariable("goOut", "recall");
            execution.setVariable("pass", "recall");
        }else if("noAgree".equals(pass.toString())){
            execution.setVariable("goOut", "noAgree");
            execution.setVariable("pass", "noAgree");
        }else if("rejectInitOwner".equals(pass.toString())){
            execution.setVariable("goOut", "rejectInitOwner");
            execution.setVariable("pass", "rejectInitOwner");
        }
        String processInstanceId = execution.getProcessInstanceId();
        Object childVariable = variables.get("childVariable");
        Object childVariableList = variables.get("childVariableList");
        String url;
        if (StringUtils.isEmpty(childVariable)) {
            String processInstanceBusinessKey = execution.getProcessInstanceBusinessKey();
            url = batchModifyStatusUrl + "?processInstanceId=" + processInstanceId+ "&businessKey=" + processInstanceBusinessKey + "&curTaskId=" + curTaskId;
        } else {
            JSONObject jsonObject = JSON.parseObject(childVariable.toString());
            String childBusinessKey = jsonObject.getString("childBusinessKey");
            url = batchModifyStatusUrl + "?processInstanceId=" + processInstanceId + "&businessKey=" + childBusinessKey + "&curTaskId=" + curTaskId;;
        }
        log.info("url:{}", url);
        httpUtil.get(url, Boolean.class);

        if ("cancel".equals(pass) && childVariableList != null) {
            JSONArray childVariableArray = JSON.parseArray(childVariableList.toString());
            for (int i = 0; i < childVariableArray.size(); i++) {
                String string = childVariableArray.getString(i);
                JSONObject jsonObject = JSON.parseObject(string);
                String childBusinessKey = jsonObject.getString("childBusinessKey");
                if(org.apache.commons.lang3.StringUtils.isNotBlank(childBusinessKey)){
                    log.info("存在子流程，将工作台子流程代办一起取消");
                    String cancelChildUrl = batchModifyStatusUrl + "?processInstanceId=" + processInstanceId + "&businessKey=" + childBusinessKey + "&curTaskId=" + curTaskId;;
                    httpUtil.get(cancelChildUrl, Boolean.class);
                }
            }
        }
        return true;
    }

    /**
     * 通过规则为：全员审批完，所有人通过则通过
     *
     * @param execution
     * @return
     */
    public Boolean acceptByAllUserCondition(DelegateExecution execution) {

        Map<String, Object> variables = execution.getVariables();
        Object agreePersonNumObject = variables.get("agreePersonNum");
        int agreePersonNum = 0;
        Object rejectPersonNumObject = variables.get("rejectPersonNum");
        int rejectPersonNum = 0;
        if (rejectPersonNumObject != null) {
            rejectPersonNum = (int) rejectPersonNumObject;
        }
        if (agreePersonNumObject != null) {
            agreePersonNum = (int) agreePersonNumObject;
        }
        Object pass = variables.get("pass");
        if (pass != null) {
            if ("pass".equals(pass.toString())) {
                agreePersonNum = agreePersonNum + 1;
                execution.setVariable("agreePersonNum", agreePersonNum);
            } else {
                rejectPersonNum = rejectPersonNum + 1;
                execution.setVariable("rejectPersonNum", rejectPersonNum);
            }

        } else {
            return Boolean.FALSE;
        }

        //已完成的实例数
        int completedInstance = (int) execution.getVariable("nrOfCompletedInstances");
        //获取所有的实例数
        int allInstance = (int) execution.getVariable("nrOfInstances");
        //已完成实例大于等于所有实例，且通过的实例数等于已完成实例数
        if (completedInstance >= allInstance && agreePersonNum == completedInstance) {
            execution.setVariable("goOut", "pass");
            //清理变量
            execution.setVariable("agreePersonNum", 0);
            execution.setVariable("rejectPersonNum", 0);
            return true;
        } else {
            return false;
        }
    }
}
